package net.maku.events.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.github.xiaoymin.knife4j.core.util.CollectionUtils;
import lombok.extern.slf4j.Slf4j;
import net.maku.events.dao.*;
import net.maku.events.entity.*;
import net.maku.events.enums.*;
import net.maku.events.query.UserSnapshotQuery;
import net.maku.events.query.WalkUserSnapshotQuery;
import net.maku.events.service.*;
import net.maku.events.utils.ListUtil;
import net.maku.events.utils.WxDecryptUtil;
import net.maku.events.vo.*;
import net.maku.framework.common.cache.RedisCache;
import net.maku.framework.common.constant.Constant;
import net.maku.framework.common.exception.ServerException;
import net.maku.framework.common.utils.*;
import net.maku.framework.mybatis.service.impl.BaseServiceImpl;
import net.maku.events.query.ActivityBriskWalkQuery;
import net.maku.framework.security.user.SecurityUser;
import net.maku.member.dao.MemberUserDao;
import net.maku.member.entity.MemberUserEntity;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * 健步走活动
 *
 * @author 阿沐 babamu@126.com
 * @since 1.0.0 2025-03-22
 */
@Slf4j
@Service
public class ActivityBriskWalkServiceImpl extends BaseServiceImpl<ActivityBriskWalkDao, ActivityBriskWalkEntity> implements ActivityBriskWalkService {

    @Autowired
    ActivityBriskWalkSiteService activityBriskWalkSiteService;
    @Autowired
    UserPointsRecordsService userPointsRecordsService;
    @Autowired
    UserJourneyDao userJourneyDao;
    @Autowired
    UserJoinActivityDao userJoinActivityDao;
    @Autowired
    UserUnlockSiteDao userUnlockSiteDao;
    @Autowired
    UserJoinActivityService userJoinActivityService;
    @Autowired
    ActivityBriskWalkFeatureDao activityBriskWalkFeatureDao;
    @Autowired
    UserSnapshotService userSnapshotService;
    @Autowired
    UserJoinBriskWalkFeatureDao userJoinBriskWalkFeatureDao;
    @Autowired
    ActivityKnowledgeContestDao activityKnowledgeContestDao;
    @Autowired
    UserContestQuestionService userContestQuestionService;
    @Autowired
    UserEverydayContestQuestionDao userEverydayContestQuestionDao;
    @Autowired
    ActivityContestQuestionService activityContestQuestionService;
    @Autowired
    UserEarningsCardDao userEarningsCardDao;
    @Autowired
    ActivityBriskWalkPointsLadderDao activityBriskWalkPointsLadderDao;
    @Autowired
    ActivityBriskWalkSiteAnswerConfigDao activityBriskWalkSiteAnswerConfigDao;
    @Autowired
    UserContestSiteAnswerRecordsDao userContestSiteAnswerRecordsDao;
    @Autowired
    UserLadderPointsDao userLadderPointsDao;
    @Autowired
    RedisCache redisCache;
    @Autowired
    MemberUserDao memberUserDao;
    @Autowired
    UserAnswerQuestionTimeService userAnswerQuestionTimeService;

    @Autowired
    private UserPointsRecordsDao userPointsRecordsDao;

    @Value("${wx.appId}")
    private String appId;

    @Value("${wx.appSecret}")
    private String appSecret;


    @Override
    public List<ActivityBaseVO> topActivity() {
        List<ActivityBriskWalkEntity> entityList = this.list(new LambdaQueryWrapper<ActivityBriskWalkEntity>().eq(ActivityBriskWalkEntity::getWhetherTop, Constant.ENABLE)
                .eq(ActivityBriskWalkEntity::getStatus, Constant.ENABLE));
        if (CollectionUtils.isNotEmpty(entityList)) {
            List<ActivityBaseVO> result = new ArrayList<>();
            entityList.forEach(item -> {
                ActivityBaseVO activityBaseVO = new ActivityBaseVO();
                activityBaseVO.setId(item.getId());
                activityBaseVO.setActivityTitle(item.getActivityTitle());
                activityBaseVO.setThumbnail(item.getActivityBanner());
                activityBaseVO.setActivityBgImage(item.getActivityBgImage());
                activityBaseVO.setTopImg(item.getTopImg());
                activityBaseVO.setActivityStatus(item.getActivityStatus());
                activityBaseVO.setBusinessType(ActivityTypeEnum.WALK_ACTIVITY.getBusinessType());
                result.add(activityBaseVO);
            });
            return result;
        }
        return List.of();
    }

    @Override
    public PageResult<ActivityBriskWalkVO> page(ActivityBriskWalkQuery query) {
        IPage<ActivityBriskWalkEntity> page = baseMapper.selectPage(getPage(query), getWrapper(query));
        List<ActivityBriskWalkVO> result = BeanUtil.copyToList(page.getRecords(), ActivityBriskWalkVO.class);
        if (CollectionUtils.isNotEmpty(page.getRecords())) {
            page.getRecords().forEach(item -> {
                item.setViewNumber(item.getViewNumber() + Constant.SUCCESS);
            });
            this.saveOrUpdateBatch(page.getRecords());
        }
        userJoinActivityService.getJoinActivityIdList(ActivityTypeEnum.WALK_ACTIVITY.getBusinessType(), result);
        return new PageResult<>(result, page.getTotal());
    }

    @Override
    public Map<String, Object> getJoinOrgIdList(Long id) {
        ActivityBriskWalkEntity entity = this.getById(id);
        Map<String, Object> result = new HashMap<>();
        result.put("orgIdList", entity.getJoinOrgId());
        result.put("bgImg", entity.getActivityBgImage());
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void joinActivity(Long id) {
        shareUserJoinActivity(id);
    }

    /**
     * 共用参与活动
     *
     * @param id 活动id
     */
    private void shareUserJoinActivity(Long id) {
        if (ObjectUtils.isEmpty(SecurityUser.getUser())) {
            throw new ServerException("用户未登录");
        }
        ActivityBriskWalkEntity activityBriskWalkEntity = this.getById(id);
        if (activityBriskWalkEntity.getActivityStatus().equals(ActivityStatusEnum.NOT_START.getStatus())) {
            throw new ServerException("活动未开始");
        }
        boolean checkFlag = userJoinActivityService.checkJoin(ActivityTypeEnum.WALK_ACTIVITY.getBusinessType(), id);
        if (checkFlag) {
            return;
        }
        if (activityBriskWalkEntity.getActivityStatus().equals(ActivityStatusEnum.END.getStatus())) {
            return;
        }
        activityBriskWalkEntity.setJoinCount(activityBriskWalkEntity.getJoinCount() + Constant.SUCCESS);
        this.updateById(activityBriskWalkEntity);
        userJoinActivityService.save(ActivityTypeEnum.WALK_ACTIVITY.getBusinessType(), id, activityBriskWalkEntity.getActivityTitle(), activityBriskWalkEntity.getActivityBanner(), activityBriskWalkEntity.getActivityStartTime(), activityBriskWalkEntity.getActivityEndTime());
        if (activityBriskWalkEntity.getFunctionPanel().contains(Constant.ENABLE)) {
            autoLightFirstStation(activityBriskWalkEntity);
        }
    }

    /**
     * 自动点亮第一个站点
     *
     * @param activityBriskWalkEntity 健步走活动
     */
    private void autoLightFirstStation(ActivityBriskWalkEntity activityBriskWalkEntity) {
//        //自动点亮第一个站点
//        List<ActivityBriskWalkSiteEntity> walkSiteEntityList = activityBriskWalkSiteService.list(new LambdaQueryWrapper<ActivityBriskWalkSiteEntity>().eq(ActivityBriskWalkSiteEntity::getWalkActivityId, activityBriskWalkEntity.getId()));
//        long differenceValue = LocalDate.now().toEpochDay() - DateUtils.utilDateToLocalDate(activityBriskWalkEntity.getActivityStartTime()).toEpochDay();
//        if (differenceValue >= walkSiteEntityList.size()) {
//            return;
//        }
//        walkSiteEntityList.sort(Comparator.comparing(ActivityBriskWalkSiteEntity::getSiteSort));
//        ActivityBriskWalkSiteEntity walkSiteEntity = walkSiteEntityList.get(Math.toIntExact(differenceValue));
//        UserUnlockSiteEntity unlockSiteEntity = new UserUnlockSiteEntity().setWalkActivityId(walkSiteEntity.getWalkActivityId()).setWalkActivitySiteId(walkSiteEntity.getId()).setSiteSort(walkSiteEntity.getSiteSort()).setUserId(SecurityUser.getUserId());
//        userUnlockSiteDao.insert(unlockSiteEntity);
//        addCard(walkSiteEntity);
        //自动点亮第一个站点
        List<ActivityBriskWalkSiteEntity> walkSiteEntityList = activityBriskWalkSiteService.list(new LambdaQueryWrapper<ActivityBriskWalkSiteEntity>().eq(ActivityBriskWalkSiteEntity::getWalkActivityId, activityBriskWalkEntity.getId()));
        walkSiteEntityList.sort(Comparator.comparing(ActivityBriskWalkSiteEntity::getSiteSort));
        ActivityBriskWalkSiteEntity walkSiteEntity = walkSiteEntityList.get(Constant.ZERO);
        UserUnlockSiteEntity unlockSiteEntity = new UserUnlockSiteEntity().setWalkActivityId(walkSiteEntity.getWalkActivityId()).setWalkActivitySiteId(walkSiteEntity.getId()).setSiteSort(walkSiteEntity.getSiteSort()).setUserId(SecurityUser.getUserId());
        userUnlockSiteDao.insert(unlockSiteEntity);
        if (walkSiteEntity.getWhetherCard().equals(Constant.ENABLE)) {
            addCard(walkSiteEntity);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void joinActivityByNewUser(NewUserJoinActivityVO joinActivityVO) {
        shareUserJoinActivity(joinActivityVO.getBriskWalkId());
        MemberUserEntity memberUser = memberUserDao.selectById(SecurityUser.getUserId());
        memberUser.setRealName(joinActivityVO.getRealName());
        memberUser.setOrgId(joinActivityVO.getOrgId());
        memberUser.setMobile(joinActivityVO.getMobile());
        memberUserDao.updateById(memberUser);
    }

    private final static String SESSION_KEY = "session_key:";
    private final static String STEP_COUNT_KEY = "step_key:";
    private final  static String MAP_UNLOCL_KEY = "map_unlock_key:";

    @Override
    public Map<String, Object> getRunCount(WeRunRequestVO request) {
        Map<String, Object> result = new HashMap<>();
        ActivityBriskWalkEntity activityBriskWalkEntity = this.getById(request.getBriskWalkId());
        long endDays = DateUtils.utilDateToLocalDate(activityBriskWalkEntity.getActivityEndTime()).toEpochDay();
        if (LocalDate.now().toEpochDay() > endDays) {
            return result;
        }
        String key = SESSION_KEY + SecurityUser.getUserId() + ":" + LocalDate.now().toEpochDay();
        Integer stepCount = Constant.ZERO;
        result.put("stepCount", stepCount);
        result.put("obtainedPoints", Constant.POINTS);
        String check = (String) redisCache.get(key);
        String sessionKey = "";
        if (StringUtils.isNotEmpty(check)) {
            sessionKey = check;
        } else {
            sessionKey = WeiXinUtils.sessoion(request.getCode(), appId, appSecret);
            redisCache.set(key, sessionKey, RedisCache.HOUR_ONE_EXPIRE);
        }
        if (StringUtils.isEmpty(sessionKey)) {
            throw new ServerException("获取SessionKey失败");
        }
        String decryptedData = WxDecryptUtil.decrypt(
                request.getEncryptedData(),
                sessionKey,
                request.getIv()
        );
        JSONObject data = JSON.parseObject(decryptedData);
        log.info("getRunCount data:{}", data);
        List<StepItemVO> steps = data.getJSONArray("stepInfoList")
                .toJavaList(StepItemVO.class);
        //进行入库操作
        Long userId = SecurityUser.getUserId();
        List<UserJourneyEntity> entityList = new ArrayList<>();
        StepItemVO stepItemVO = steps.get(steps.size() - 1);
        UserJourneyEntity entity = BeanUtil.copyProperties(stepItemVO, UserJourneyEntity.class);
        if (activityBriskWalkEntity.getDailyCapping() > stepItemVO.getStep()) {
            entity.setStepNumber(stepItemVO.getStep());
        } else {
            entity.setStepNumber(activityBriskWalkEntity.getDailyCapping());
        }
        String stepKey = STEP_COUNT_KEY + request.getBriskWalkId() + ":" + SecurityUser.getUserId() + ":" + LocalDate.now().toEpochDay();

        redisCache.set(stepKey, entity.getStepNumber(), RedisCache.DEFAULT_EXPIRE);
        // 计算当天 23:59:54 的剩余秒数
        LocalDateTime endOfDayMinus5Sec = LocalDate.now()
                .atTime(23, 59, 59)  // 当天 23:59:59
                .minusSeconds(5);     // 减去 5 秒 → 23:59:54

        // 计算当前时间到 23:59:54 的剩余秒数
        long secondsUntilExpire = Duration.between(LocalDateTime.now(), endOfDayMinus5Sec)
                .getSeconds();
        String mapUnlockKey = MAP_UNLOCL_KEY + request.getBriskWalkId() + ":" + SecurityUser.getUserId();
        redisCache.set(mapUnlockKey,entity.getStepNumber(),Math.max(1, secondsUntilExpire));
        entityList.add(entity);
        if (CollectionUtils.isNotEmpty(entityList)) {
            UserJourneyEntity userJourneyEntity = entityList.get(entityList.size() - Constant.SUCCESS);
            result.put("stepCount", userJourneyEntity.getStepNumber());
            result.put("obtainedPoints", calcLadderPoints(userJourneyEntity.getStepNumber(), request.getBriskWalkId()));
            return result;
        }
        return result;
    }

//    @Override
//    public Map<String, Object> getRunCount(WeRunRequestVO request) {
//        String key = SESSION_KEY + SecurityUser.getUserId() + ":" + LocalDate.now().toEpochDay();
//        Map<String, Object> result = new HashMap<>();
//        Integer stepCount = Constant.ZERO;
//        result.put("stepCount", stepCount);
//        result.put("obtainedPoints", Constant.POINTS);
//        String check = (String) redisCache.get(key);
//        String sessionKey = "";
//        if (StringUtils.isNotEmpty(check)) {
//            sessionKey = check;
//        } else {
//            sessionKey = WeiXinUtils.sessoion(request.getCode(), appId, appSecret);
//            redisCache.set(key, sessionKey, RedisCache.DEFAULT_EXPIRE);
//        }
//        if (StringUtils.isEmpty(sessionKey)) {
//            throw new ServerException("获取SessionKey失败");
//        }
//        String decryptedData = WxDecryptUtil.decrypt(
//                request.getEncryptedData(),
//                sessionKey,
//                request.getIv()
//        );
//        JSONObject data = JSON.parseObject(decryptedData);
//        List<StepItemVO> steps = data.getJSONArray("stepInfoList")
//                .toJavaList(StepItemVO.class);
//        //进行入库操作
//        Long userId = SecurityUser.getUserId();
//        //改成删除当天的数据
//        UserJourneyEntity userJourneyEntity = userJourneyDao.selectOne(new LambdaQueryWrapper<UserJourneyEntity>().eq(UserJourneyEntity::getUserId, userId)
//                .eq(UserJourneyEntity::getStepDate, LocalDate.now())
//                .eq(UserJourneyEntity::getWalkActivityId, request.getBriskWalkId()));
//        ActivityBriskWalkEntity activityBriskWalkEntity = this.getById(request.getBriskWalkId());
//        long endDays = DateUtils.utilDateToLocalDate(activityBriskWalkEntity.getActivityEndTime()).toEpochDay();
//        if (LocalDate.now().toEpochDay() > endDays) {
//            return result;
//        }
//        StepItemVO stepItemVO = steps.get(steps.size() - 1);
//        int stepNumber = 0;
//        if (activityBriskWalkEntity.getDailyCapping() > stepItemVO.getStep()) {
//            stepNumber = stepItemVO.getStep();
//        } else {
//            stepNumber = activityBriskWalkEntity.getDailyCapping();
//        }
//        if (ObjectUtils.isNotEmpty(userJourneyEntity)) {
//            userJourneyEntity.setStepNumber(stepNumber);
//        } else {
//            userJourneyEntity = new UserJourneyEntity();
//            userJourneyEntity.setStepNumber(stepNumber);
//            userJourneyEntity.setUserId(userId);
//            userJourneyEntity.setStepDate(stepItemVO.getTimestamp());
//            userJourneyEntity.setWalkActivityId(request.getBriskWalkId());
//        }
//        userJourneyDao.insertOrUpdate(userJourneyEntity);
//        if (ObjectUtils.isNotEmpty(userJourneyEntity)) {
//            result.put("stepCount", userJourneyEntity.getStepNumber());
//            result.put("obtainedPoints", calcLadderPoints(userJourneyEntity.getStepNumber(), request.getBriskWalkId()));
//            return result;
//        }
//        return result;
//    }

    /**
     * 计算阶梯得分
     *
     * @param stepNumber  步数
     * @param briskWalkId 健步走id
     */
    private Double calcLadderPoints(Integer stepNumber, Long briskWalkId) {
        if (stepNumber >= 3500) {
            List<ActivityBriskWalkPointsLadderEntity> walkPointsLadderEntityList = activityBriskWalkPointsLadderDao.selectList(new LambdaQueryWrapper<ActivityBriskWalkPointsLadderEntity>()
                    .eq(ActivityBriskWalkPointsLadderEntity::getBriskWalkId, briskWalkId));
            if (CollectionUtils.isNotEmpty(walkPointsLadderEntityList)) {
                List<UserLadderPointsEntity> userLadderPointsEntityList = userLadderPointsDao.selectList(new LambdaQueryWrapper<UserLadderPointsEntity>()
                        .eq(UserLadderPointsEntity::getWalkActivityId, briskWalkId)
                        .eq(UserLadderPointsEntity::getUserId, SecurityUser.getUserId())
                        .le(UserLadderPointsEntity::getCheckDate, LocalDateTime.of(LocalDate.now(), LocalTime.MAX))
                        .ge(UserLadderPointsEntity::getCheckDate, LocalDateTime.of(LocalDate.now(), LocalTime.MIN)));
                List<Long> ladderPointsIdList = new ArrayList<>();
                double obtainedPoints = Constant.POINTS;
                if (CollectionUtils.isNotEmpty(userLadderPointsEntityList)) {
                    //已经得过积分
                    ladderPointsIdList.addAll(userLadderPointsEntityList.stream().map(UserLadderPointsEntity::getPointsLadderId).toList());
                    obtainedPoints = userLadderPointsEntityList.stream().mapToDouble(UserLadderPointsEntity::getPoints).sum();
                }
                if (obtainedPoints >= 10) {
                    return Constant.POINTS;
                }
                List<ActivityBriskWalkPointsLadderEntity> canAddPointsEntityList = walkPointsLadderEntityList.stream().filter(item -> item.getStepNumber() <= stepNumber && !ladderPointsIdList.contains(item.getId())).toList();
                double newObtainedPoints = Constant.POINTS;
                if (CollectionUtils.isNotEmpty(canAddPointsEntityList)) {
                    List<UserLadderPointsEntity> needAddEntity = new ArrayList<>();
                    for (ActivityBriskWalkPointsLadderEntity activityBriskWalkPointsLadderEntity : canAddPointsEntityList) {
                        if (obtainedPoints <= 10) {
                            obtainedPoints += activityBriskWalkPointsLadderEntity.getPoints();
                            newObtainedPoints += activityBriskWalkPointsLadderEntity.getPoints();
                            UserLadderPointsEntity userLadderPoints = new UserLadderPointsEntity();
                            userLadderPoints.setPointsLadderId(activityBriskWalkPointsLadderEntity.getId());
                            userLadderPoints.setCheckDate(LocalDate.now());
                            userLadderPoints.setStepNumber(activityBriskWalkPointsLadderEntity.getStepNumber());
                            userLadderPoints.setWalkActivityId(briskWalkId);
                            userLadderPoints.setPoints(activityBriskWalkPointsLadderEntity.getPoints());
                            userLadderPoints.setUserId(SecurityUser.getUserId());
                            needAddEntity.add(userLadderPoints);
                            userPointsRecordsService.insertUserPointsRecords(briskWalkId, ActivityTypeEnum.WALK_ACTIVITY.getBusinessType(), activityBriskWalkPointsLadderEntity.getPoints(), WhetherAddEnum.ADD.getType());
                        } else {
                            break;
                        }
                    }
                    userLadderPointsDao.insertOrUpdate(needAddEntity);
                    return newObtainedPoints;
                }
            }
        }
        return Constant.POINTS;
    }


    @Override
    //@Transactional(rollbackFor = Exception.class)
    public void unlockSite(Long id, Long siteId) {
        Long userId = SecurityUser.getUserId();
        if (userId == null) {
            userId = 23007L;
        }
        String lockKey = "lock:walk_activity:" + userId + ":" + id;
        String lockValue = UUID.randomUUID().toString();
        // 尝试获取锁（设置 10 秒超时）


        try {
            // 尝试获取锁（10秒超时）
            if (!redisCache.setIfAbsent(lockKey, lockValue, 30)) {
                throw new ServerException("操作过于频繁，请稍后再试");
            }
            log.info("unlockSite 用户 {} 尝试解锁站点 {}, 锁Key={}", userId, siteId, lockKey);




            // 获取当前日期
            LocalDate today = LocalDate.now();
            // 获取当天的开始时间（00:00:00）
            LocalDateTime startOfDay = today.atStartOfDay();
            // 获取当天的结束时间（23:59:59.999...）
            LocalDateTime endOfDay = today.atTime(LocalTime.MAX);
            ActivityBriskWalkSiteEntity siteEntity = activityBriskWalkSiteService.getById(siteId);
            if (ObjectUtils.isEmpty(siteEntity)) {
                throw new ServerException("该站点不存在");
            }
            UserUnlockSiteEntity checkUnlock = userUnlockSiteDao.selectOne(new LambdaQueryWrapper<UserUnlockSiteEntity>().eq(UserUnlockSiteEntity::getWalkActivityId, id)
                    .eq(UserUnlockSiteEntity::getWalkActivitySiteId, siteId)
                    .eq(UserUnlockSiteEntity::getUserId, userId));
            if (ObjectUtils.isNotEmpty(checkUnlock)) {
                throw new ServerException("该站点已解锁");
            }
            List<UserJourneyEntity> userJourneyEntityList = userJourneyDao.selectList(new LambdaQueryWrapper<UserJourneyEntity>().eq(UserJourneyEntity::getWalkActivityId, id)
                    .eq(UserJourneyEntity::getUserId, userId));
            //需要判断是否是开启了固定步数解锁站点---每日解锁
            ActivityBriskWalkEntity walkEntity = this.getById(id);
            if (!walkEntity.getActivityStatus().equals(Constant.ENABLE)) {
                throw new ServerException("该站点未开始或已结束");
            }
            if (walkEntity.getWhetherFixation().equals(Constant.ZERO)) {
                if (!siteEntity.getUnlockStepNumber().equals(Constant.ZERO)) {
                    if (CollectionUtils.isEmpty(userJourneyEntityList)) {
                        throw new ServerException("步数未达到解锁条件");
                    }
                    int totalSteps = userJourneyEntityList.stream()
                            .filter(Objects::nonNull)
                            .mapToInt(entity -> entity.getStepNumber() != null ? entity.getStepNumber() : 0)
                            .sum();
                    if (siteEntity.getUnlockStepNumber() > totalSteps) {
                        throw new ServerException("步数未达到解锁条件");
                    }
                }
            } else {


                //固定步数
                UserJoinActivityEntity userJoinActivityEntity = userJoinActivityService.getOne(new LambdaQueryWrapper<UserJoinActivityEntity>().eq(UserJoinActivityEntity::getBusinessType, ActivityTypeEnum.WALK_ACTIVITY.getBusinessType())
                        .eq(UserJoinActivityEntity::getActivityId, id)
                        .eq(UserJoinActivityEntity::getUserId, userId));
                if (ObjectUtils.isEmpty(userJoinActivityEntity)) {
                    throw new ServerException("未参与活动");
                }
                if (siteId == 244) {
                    // 不需要步数解锁
                    long countFistSite = userUnlockSiteDao.selectCount(new LambdaQueryWrapper<UserUnlockSiteEntity>().eq(UserUnlockSiteEntity::getWalkActivitySiteId, 244)
                            .eq(UserUnlockSiteEntity::getUserId, userId)
                            .eq(UserUnlockSiteEntity::getWalkActivityId, id));
                    if (countFistSite > 0) {
                        return;
                    }
                    addCard(siteEntity);
                    UserUnlockSiteEntity unlockSiteEntity = new UserUnlockSiteEntity().setWalkActivityId(id).setWalkActivitySiteId(siteId).setUserId(userId).setSiteSort(siteEntity.getSiteSort());
                    userUnlockSiteDao.insert(unlockSiteEntity);

                    userPointsRecordsService.insertUserPointsRecords(id, ActivityTypeEnum.WALK_ACTIVITY.getBusinessType(), siteEntity.getUnlockPoints(), WhetherAddEnum.ADD.getType());
                    return;
                }
                //  查询缓存
//                String mapUnlockKey = MAP_UNLOCL_KEY + id + ":" + SecurityUser.getUserId();
//                Object stepNumber = redisCache.get(mapUnlockKey);
//                if (stepNumber !=null ){
//                    int number = Integer.parseInt(stepNumber.toString());
//                    if (number < walkEntity.getFixationStep()){
//                        throw new ServerException("步数暂未达到解锁条件");
//                    }
//                    log.info("unlock 步数达到  stepCountFound > 0  {} {} step_redis {}",userId,walkEntity.getFixationStep(),stepNumber);
//                }else {
                    // 查询数据库中数据
                    Date todayD = java.sql.Date.valueOf(LocalDate.now());

                    QueryWrapper<UserJourneyEntity> queryWrapper = new QueryWrapper<UserJourneyEntity>();
                    queryWrapper.eq("user_id", userId);
                    queryWrapper.eq("walk_activity_id", id);
                    queryWrapper.ge("step_number", walkEntity.getFixationStep());
                    queryWrapper.eq("deleted",0);
                    queryWrapper.eq("step_date", todayD);
                    List<UserJourneyEntity> userJourneys= userJourneyDao.selectList(queryWrapper);
                    log.info("unlock sql查询结果   userId {} userJ  {}", userId, userJourneys);
                    if (userJourneys == null || userJourneys.size() <= 0) {
                        throw new ServerException("步数暂未达到解锁条件");
                    }
                    log.info("unlock 步数达到  stepCountFound > 0  {} {} step_date {} ",userId,walkEntity.getFixationStep(),todayD);
//                }




                // 查询今天是否解锁了地图
                QueryWrapper<UserUnlockSiteEntity> userUnlockSiteEntityQueryWrapper = new QueryWrapper<UserUnlockSiteEntity>();
                userUnlockSiteEntityQueryWrapper.eq("user_id", userId);
                userUnlockSiteEntityQueryWrapper.eq("walk_activity_id", id);
                userUnlockSiteEntityQueryWrapper.orderByDesc("walk_activity_site_id");
                List<UserUnlockSiteEntity> userUnlockSiteEntities = userUnlockSiteDao.selectList(userUnlockSiteEntityQueryWrapper);
                if (userUnlockSiteEntities == null || userUnlockSiteEntities.size() == 0) {
                    throw new ServerException("请先解锁第一个");
                }
                UserUnlockSiteEntity unlockSiteEntity = userUnlockSiteEntities.get(0);
                LocalDateTime createTime = unlockSiteEntity.getCreateTime();
                long siteIdFound = unlockSiteEntity.getWalkActivitySiteId();
                if (!createTime.isBefore(startOfDay) && !createTime.isAfter(endOfDay) && siteIdFound != 244) {
                    throw new ServerException("当天已解锁,不能再次解锁");
                }
                if (siteIdFound + 1 != siteId) {
                    throw new ServerException("请按顺序解锁");
                }

                addCard(siteEntity);
                UserUnlockSiteEntity unlockSiteEntityNew = new UserUnlockSiteEntity().setWalkActivityId(id).setWalkActivitySiteId(siteId).setUserId(userId).setSiteSort(siteEntity.getSiteSort());
                userUnlockSiteDao.insert(unlockSiteEntityNew);
                userPointsRecordsService.insertUserPointsRecords(id, ActivityTypeEnum.WALK_ACTIVITY.getBusinessType(), siteEntity.getUnlockPoints(), WhetherAddEnum.ADD.getType());
            }
        } finally {
            try {
                redisCache.releaseLock(lockKey, lockValue);
            } catch (Exception e) {
                log.error("释放锁失败, key={}, value={}", lockKey, lockValue, e);
            }
        }


    }

    @Override
    public ActivityBriskWalkVO getInfoById(Long id) throws InterruptedException {
        ActivityBriskWalkVO activityBriskWalkVO = BeanUtil.copyProperties(this.getById(id), ActivityBriskWalkVO.class);
//        CountDownLatch latch = new CountDownLatch(3);
        Long userId = SecurityUser.getUserId();
//        ThreadPoolExecutorUtil.getThreadPool().execute(() -> {
//            //设置站点信息及其他
//            setFeatureData(id, userId, activityBriskWalkVO);
//            latch.countDown();
//        });
//        ThreadPoolExecutorUtil.getThreadPool().execute(() -> {
//            //设置参与人数与步数及计算公里数
//            setJoinUserAndStep(id, userId, activityBriskWalkVO);
//            latch.countDown();
//        });
//        ThreadPoolExecutorUtil.getThreadPool().execute(() -> {
//            //设置累计积分
//            setActivityPoints(id, userId, activityBriskWalkVO);
//            latch.countDown();
//        });
//        latch.await();
        setFeatureData(id, userId, activityBriskWalkVO);
        setJoinUserAndStep(id, userId, activityBriskWalkVO);
        setActivityPoints(id, userId, activityBriskWalkVO);
        return activityBriskWalkVO;
    }

    @Override
    public ActivityBriskWalkVO division(Long id) {
        ActivityBriskWalkVO activityBriskWalkVO = BeanUtil.copyProperties(this.getById(id), ActivityBriskWalkVO.class);
        setFeatureData(id, SecurityUser.getUserId(), activityBriskWalkVO);
        return activityBriskWalkVO;
    }

    @Override
    public ActivityBriskWalkVO setJoinUserAndStep(Long id) {
        ActivityBriskWalkVO activityBriskWalkVO = new ActivityBriskWalkVO();
        setJoinUserAndStep(id, SecurityUser.getUserId(), activityBriskWalkVO);
        return activityBriskWalkVO;
    }

    @Override
    public ActivityBriskWalkVO setActivityPoints(Long id) {
        ActivityBriskWalkVO activityBriskWalkVO = new ActivityBriskWalkVO();
        setActivityPoints(id, SecurityUser.getUserId(), activityBriskWalkVO);
        return activityBriskWalkVO;
    }

    /**
     * 设置站点信息及其他
     *
     * @param id                  健步走主键
     * @param activityBriskWalkVO 返回结果
     */
    private void setFeatureData(Long id, Long userId, ActivityBriskWalkVO activityBriskWalkVO) {
        List<ActivityBriskWalkFeatureVO> activityBriskWalkFeatureList = BeanUtil.copyToList(activityBriskWalkFeatureDao.selectList(new LambdaQueryWrapper<ActivityBriskWalkFeatureEntity>()
                        .eq(ActivityBriskWalkFeatureEntity::getBriskWalkId, id)),
                ActivityBriskWalkFeatureVO.class);
        if (CollectionUtils.isNotEmpty(activityBriskWalkFeatureList)) {
            List<UserJoinBriskWalkFeatureEntity> joinBriskWalkFeatureList = userJoinBriskWalkFeatureDao.selectList(new LambdaQueryWrapper<UserJoinBriskWalkFeatureEntity>().in(UserJoinBriskWalkFeatureEntity::getWalkFeatureId, activityBriskWalkFeatureList.stream().map(ActivityBriskWalkFeatureVO::getId).collect(Collectors.toList()))
                    .eq(UserJoinBriskWalkFeatureEntity::getBriskWalkId, id).eq(UserJoinBriskWalkFeatureEntity::getUserId, userId));
            if (CollectionUtils.isNotEmpty(joinBriskWalkFeatureList)) {
                Map<Long, UserJoinBriskWalkFeatureEntity> walkFeatureIdMap = joinBriskWalkFeatureList.stream().collect(Collectors.toMap(UserJoinBriskWalkFeatureEntity::getWalkFeatureId, Function.identity()));
                Set<Long> ketSet = walkFeatureIdMap.keySet();
                activityBriskWalkFeatureList.forEach(item -> {
                    if (ketSet.contains(item.getId())) {
                        item.setAlreadyJoin(true);
                        UserJoinBriskWalkFeatureEntity entity = walkFeatureIdMap.get(item.getId());
                        item.setWhetherComplete(entity.getWhetherComplete().equals(Constant.COMPLETE));
                        if (item.getWhetherRandom().equals(WhetherRandomEnum.YES.getType())) {
                            //还需要判断今日是否参与
                            if (entity.getUpdateTime().toLocalDate().toEpochDay() == LocalDate.now().toEpochDay()) {
                                item.setTodayComplete(true);
                            }
                        }
                    }
                });
            }
        }
        activityBriskWalkVO.setActivityBriskWalkFeatureList(activityBriskWalkFeatureList);
    }

    /**
     * 设置参与人数与步数及计算公里数
     *
     * @param id                  健步走id
     * @param userId              用户id
     * @param activityBriskWalkVO 返回对象
     */
    private void setJoinUserAndStep(Long id, Long userId, ActivityBriskWalkVO activityBriskWalkVO) {
        //获取参与职工人数
        List<UserJoinActivityEntity> joinActivityEntityList = userJoinActivityDao.selectList(new LambdaQueryWrapper<UserJoinActivityEntity>().eq(UserJoinActivityEntity::getBusinessType, ActivityTypeEnum.WALK_ACTIVITY.getBusinessType())
                .eq(UserJoinActivityEntity::getActivityId, id));
        if (CollectionUtils.isNotEmpty(joinActivityEntityList)) {
            activityBriskWalkVO.setParticipantsNumber(joinActivityEntityList.size());
            List<Long> joinUserIdList = joinActivityEntityList.stream().map(UserJoinActivityEntity::getUserId).collect(Collectors.toList());
            if (joinUserIdList.contains(userId)) {
                activityBriskWalkVO.setJoinFlag(true);
            }
            //设置步数
            List<UserJourneyEntity> journeyEntityList = userJourneyDao.selectList(new LambdaQueryWrapper<UserJourneyEntity>().in(UserJourneyEntity::getUserId, joinUserIdList)
                    .eq(UserJourneyEntity::getWalkActivityId, id));
            if (CollectionUtils.isNotEmpty(journeyEntityList)) {
                int stepNumber = journeyEntityList.stream().filter(item -> ObjectUtils.isNotEmpty(item.getStepNumber())).mapToInt(UserJourneyEntity::getStepNumber).sum();
                String stepKey = STEP_COUNT_KEY + id + ":" + SecurityUser.getUserId() + ":" + LocalDate.now().toEpochDay();
                int selfStepNumber = 0;
                Integer selfStepNumberCount = (Integer) redisCache.get(stepKey);
                if (ObjectUtils.isNotEmpty(selfStepNumberCount)) {
                    selfStepNumber = selfStepNumberCount.intValue();
                } else {
                    selfStepNumber = journeyEntityList.stream().filter(item -> ObjectUtils.isNotEmpty(item.getStepNumber()) && item.getUserId().equals(userId)).mapToInt(UserJourneyEntity::getStepNumber).sum();
                    activityBriskWalkVO.setCumulativeSteps(stepNumber);
                }
                activityBriskWalkVO.setSelfCumulativeSteps(selfStepNumber);
                //设置公里数
                //设置消耗卡路里
                if (stepNumber != 0) {
                    double kilometres = Double.parseDouble(String.format("%.2f", stepNumber / (1500 * 1.0)));
                    activityBriskWalkVO.setKilometres(kilometres);
                    double caloriesBurned = 60 * kilometres * 0.7;
                    activityBriskWalkVO.setCumulativeCaloriesBurned(Double.parseDouble(String.format("%.2f", caloriesBurned)));
                }
                if (selfStepNumber != 0) {
                    double kilometres = Double.parseDouble(String.format("%.2f", selfStepNumber / (1500 * 1.0)));
                    activityBriskWalkVO.setSelfKilometres(kilometres);
                }
            }
        }
    }

    /**
     * 设置累计积分
     *
     * @param id                  健步走id
     * @param activityBriskWalkVO 返回对象
     */
    private void setActivityPoints(Long id, Long userId, ActivityBriskWalkVO activityBriskWalkVO) {
        //获取累计积分
//        List<UserPointsRecordsEntity> pointsRecordsEntityList = userPointsRecordsService.list(new LambdaQueryWrapper<UserPointsRecordsEntity>().eq(UserPointsRecordsEntity::getBusinessType, ActivityTypeEnum.WALK_ACTIVITY.getBusinessType())
//                .eq(UserPointsRecordsEntity::getBusinessId, id));
//        if (CollectionUtils.isNotEmpty(pointsRecordsEntityList)) {
//            activityBriskWalkVO.setTotalPoints(pointsRecordsEntityList.stream().filter(item -> ObjectUtils.isNotEmpty(item.getPoints())).mapToDouble(UserPointsRecordsEntity::getPoints).sum());
//        }
        activityBriskWalkVO.setActivityBriskWalkPointsLadderList(BeanUtil.copyToList(activityBriskWalkPointsLadderDao.selectList(new LambdaQueryWrapper<ActivityBriskWalkPointsLadderEntity>()
                .eq(ActivityBriskWalkPointsLadderEntity::getBriskWalkId, id)), ActivityBriskWalkPointsLadderVO.class));
        List<UserJourneyEntity> todayEntityList = userJourneyDao.selectList(new LambdaQueryWrapper<UserJourneyEntity>().eq(UserJourneyEntity::getUserId, userId)
                .eq(UserJourneyEntity::getWalkActivityId, id)
                .apply("date_format(step_date,'%Y-%m-%d') = date_format ({0},'%Y-%m-%d')", DateUtils.format(new Date(), DateUtils.DATE_PATTERN)));
        if (CollectionUtils.isNotEmpty(todayEntityList)) {
            Iterator<UserJourneyEntity> iterator = todayEntityList.iterator();
            while (iterator.hasNext()) {
                UserJourneyEntity entity = iterator.next();
                // 如果不是最后一条，就删除
                if (todayEntityList.indexOf(entity) < todayEntityList.size() - 1) {
                    userJourneyDao.deleteById(entity.getId());
                    iterator.remove(); // 安全删除
                }
            }
            UserJourneyEntity todayEntity = todayEntityList.get(0);
            String stepKey = STEP_COUNT_KEY + id + ":" + SecurityUser.getUserId() + ":" + LocalDate.now().toEpochDay();
            Integer selfStepNumberCount = (Integer) redisCache.get(stepKey);
            if (ObjectUtils.isNotEmpty(selfStepNumberCount)) {
                activityBriskWalkVO.setTodaySteps(selfStepNumberCount.intValue());
            } else {
                activityBriskWalkVO.setTodaySteps(todayEntity.getStepNumber());
            }
            if (todayEntity.getStepNumber() != 0) {
                double kilometres = Double.parseDouble(String.format("%.2f", todayEntity.getStepNumber() / (1500 * 1.0)));
                activityBriskWalkVO.setTodayKilometres(kilometres);
                double caloriesBurned = 60 * kilometres * 0.7;
                activityBriskWalkVO.setTodayCumulativeCaloriesBurned(Double.parseDouble(String.format("%.2f", caloriesBurned)));
            }
        }


//        UserJourneyEntity todayEntity = userJourneyDao.selectOne(new LambdaQueryWrapper<UserJourneyEntity>().eq(UserJourneyEntity::getUserId, userId)
//                .eq(UserJourneyEntity::getWalkActivityId, id)
//                .apply("date_format(step_date,'%Y-%m-%d') = date_format ({0},'%Y-%m-%d')", DateUtils.format(new Date(), DateUtils.DATE_PATTERN)));
//        if (ObjectUtils.isNotEmpty(todayEntity)) {
//            String stepKey = STEP_COUNT_KEY + id + ":" + SecurityUser.getUserId() + ":" + LocalDate.now().toEpochDay();
//            Integer selfStepNumberCount = (Integer) redisCache.get(stepKey);
//            if (ObjectUtils.isNotEmpty(selfStepNumberCount)) {
//                activityBriskWalkVO.setTodaySteps(selfStepNumberCount.intValue());
//            } else {
//                activityBriskWalkVO.setTodaySteps(todayEntity.getStepNumber());
//            }
//            if (todayEntity.getStepNumber() != 0) {
//                double kilometres = Double.parseDouble(String.format("%.2f", todayEntity.getStepNumber() / (1500 * 1.0)));
//                activityBriskWalkVO.setTodayKilometres(kilometres);
//                double caloriesBurned = 60 * kilometres * 0.7;
//                activityBriskWalkVO.setTodayCumulativeCaloriesBurned(Double.parseDouble(String.format("%.2f", caloriesBurned)));
//            }
//        }
    }


    @Override
    public List<ActivityBriskWalkSiteVO> viewCompetitionMap(Long id) {
        List<ActivityBriskWalkSiteVO> briskWalkSiteVOList = activityBriskWalkSiteService.getSiteData(id);
        //查询用户已解锁的站点
        List<UserUnlockSiteEntity> unlockSiteEntityList = userUnlockSiteDao.selectList(new LambdaQueryWrapper<UserUnlockSiteEntity>().eq(UserUnlockSiteEntity::getWalkActivityId, id).eq(UserUnlockSiteEntity::getUserId, SecurityUser.getUserId()));
        if (CollectionUtils.isNotEmpty(unlockSiteEntityList)) {
            Map<Long, UserUnlockSiteEntity> unlockSiteMap = unlockSiteEntityList.stream().collect(Collectors.toMap(UserUnlockSiteEntity::getWalkActivitySiteId, Function.identity()));
            briskWalkSiteVOList.forEach(item -> {
                if (ObjectUtils.isNotEmpty(unlockSiteMap.get(item.getId()))) {
                    item.setUnlockFlag(true);
                }
            });
        }
        return briskWalkSiteVOList;
    }

    /**
     * 添加用户参与的关联活动
     *
     * @param featureEntity 关联对象
     */
    private void setUserJoinFeatureActivity(ActivityBriskWalkFeatureEntity featureEntity) {
        //需要判断是否是知识竞赛以及是每日答题
        UserJoinBriskWalkFeatureEntity checkEntity = null;
        boolean whetherComplete = false;
        if (featureEntity.getWhetherRandom().equals(WhetherRandomEnum.YES.getType())) {
            checkEntity = userJoinBriskWalkFeatureDao.selectOne(new LambdaQueryWrapper<UserJoinBriskWalkFeatureEntity>()
                    .eq(UserJoinBriskWalkFeatureEntity::getBriskWalkId, featureEntity.getBriskWalkId())
                    .eq(UserJoinBriskWalkFeatureEntity::getUserId, SecurityUser.getUserId())
                    .eq(UserJoinBriskWalkFeatureEntity::getWalkFeatureId, featureEntity.getId()));
            ActivityBriskWalkEntity activityBriskWalkEntity = this.getById(featureEntity.getBriskWalkId());
            if (DateUtils.utilDateToLocalDate(activityBriskWalkEntity.getActivityEndTime()).equals(DateUtils.utilDateToLocalDate(new Date()))) {
                whetherComplete = true;
            }
        } else {
            whetherComplete = true;
        }
        if (ObjectUtils.isEmpty(checkEntity)) {
            UserJoinBriskWalkFeatureEntity userJoinBriskWalkFeatureEntity = new UserJoinBriskWalkFeatureEntity().setUserId(SecurityUser.getUserId())
                    .setBriskWalkId(featureEntity.getBriskWalkId())
                    .setBusinessId(featureEntity.getBusinessId())
                    .setBusinessType(featureEntity.getBusinessType())
                    .setBusinessIcon(featureEntity.getBusinessIcon())
                    .setBusinessName(featureEntity.getBusinessName())
                    .setWalkFeatureId(featureEntity.getId())
                    .setRandomNumber(featureEntity.getRandomNumber())
                    .setWhetherRandom(featureEntity.getWhetherRandom())
                    .setWhetherComplete(whetherComplete ? Constant.COMPLETE : Constant.FAIL);
            userJoinBriskWalkFeatureDao.insert(userJoinBriskWalkFeatureEntity);
        } else {
            if (whetherComplete) {
                checkEntity.setWhetherComplete(Constant.COMPLETE);
            }
            userJoinBriskWalkFeatureDao.updateById(checkEntity);
        }
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public double saveUserSnapshot(BriskWalkSnapshotVO vo) {
        //健步走发布随手拍
        ActivityBriskWalkEntity activityBriskWalkEntity = this.getById(vo.getBriskWalkId());
        if (ObjectUtils.isEmpty(activityBriskWalkEntity)) {
            throw new ServerException("该健步走不存在");
        }
        ActivityBriskWalkFeatureEntity featureEntity = activityBriskWalkFeatureDao.selectById(vo.getWalkFeatureId());
        if (ObjectUtils.isEmpty(featureEntity)) {
            throw new ServerException("该健步走未配置随手拍活动");
        }
        //校验是否已经拍过
        boolean check = userSnapshotService.checkAlreadySave(vo.getBriskWalkId(), vo.getRiskWalkSiteId(), ActivityTypeEnum.WALK_ACTIVITY.getBusinessType(), featureEntity.getWhetherRandom().equals(WhetherRandomEnum.YES.getType()));
        if (check) {
            throw new ServerException("随手拍已完成");
        }
        setUserJoinFeatureActivity(featureEntity);
        UserSnapshotVO userSnapshotVO = BeanUtil.copyProperties(vo, UserSnapshotVO.class);
        userSnapshotVO.setSnapshotId(featureEntity.getBusinessId());
        userSnapshotService.save(vo.getBriskWalkId(), vo.getRiskWalkSiteId(), vo.getWalkFeatureId(), ActivityTypeEnum.WALK_ACTIVITY.getBusinessType(), userSnapshotVO);
//        //这个需要改到后台进行审核通过之后再给分
//        if (featureEntity.getWhetherPoints().equals(WhetherPointsEnum.YES.getType())) {
//            //是否增加积分
//            ActivitySnapshotEntity activitySnapshotEntity = activitySnapshotService.getById(featureEntity.getBusinessId());
//            if (ObjectUtils.isNotEmpty(activitySnapshotEntity)) {
//                userPointsRecordsService.insertUserPointsRecords(vo.getBriskWalkId(), ActivityTypeEnum.WALK_ACTIVITY.getBusinessType(), activitySnapshotEntity.getEarningsPoints(), WhetherAddEnum.ADD.getType());
//                return activitySnapshotEntity.getEarningsPoints();
//            }
//        }
        return Constant.POINTS;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public double answer(BriskWalkAnswerQuestionVO vo) {
        //需要判断是否是站点答题
        double points = 0.0;
        if (ObjectUtils.isEmpty(vo.getBriskWalkSiteId())) {
            ActivityBriskWalkFeatureEntity featureEntity = activityBriskWalkFeatureDao.selectById(vo.getWalkFeatureId());
            if (ObjectUtils.isEmpty(featureEntity)) {
                throw new ServerException("该健步走未配置知识竞赛活动");
            }
            //获取竞赛数据
            ActivityKnowledgeContestEntity knowledgeContestEntity = activityKnowledgeContestDao.selectById(featureEntity.getBusinessId());
            if (ObjectUtils.isEmpty(knowledgeContestEntity)) {
                throw new ServerException("该知识竞赛不存在");
            }
            checkAnswer(null, featureEntity);
            if (featureEntity.getBusinessType().equals(ActivityTypeEnum.KNOWLEDGE_CONTEST.getBusinessType()) && featureEntity.getWhetherRandom().equals(WhetherRandomEnum.YES.getType())) {
                UserEverydayContestQuestionEntity everydayContestQuestionEntity = new UserEverydayContestQuestionEntity();
                everydayContestQuestionEntity.setUserId(SecurityUser.getUserId());
                everydayContestQuestionEntity.setWalkActivityId(featureEntity.getBriskWalkId());
                everydayContestQuestionEntity.setWalkFeatureId(featureEntity.getId());
                everydayContestQuestionEntity.setContestQuestionIds(vo.getUserAnswerQuestionBankList().stream().map(UserAnswerQuestionBankVO::getId).collect(Collectors.toList()));
                userEverydayContestQuestionDao.insert(everydayContestQuestionEntity);
            }
            setUserJoinFeatureActivity(featureEntity);
            points = userContestQuestionService.
                    save(vo.getBriskWalkId(), null, featureEntity.getBusinessId(), ActivityQuestionTypeEnum.KNOWLEDGE_CONTEST.getBusinessType(), vo.getUserAnswerQuestionBankList());
            if (featureEntity.getWhetherPoints().equals(WhetherPointsEnum.NO.getType())) {
                points = 0;
            }
            userAnswerQuestionTimeService.completedUserAnswerQuestion(vo.getBriskWalkId(), featureEntity.getBusinessId(), UserAnswerQuestionEnum.WALK_ACTIVITY.getType());
        } else {
            ActivityBriskWalkSiteEntity walkSiteEntity = activityBriskWalkSiteService.getById(vo.getBriskWalkSiteId());
            if (ObjectUtils.isEmpty(walkSiteEntity)) {
                throw new ServerException("该站点不存在");
            }
            if (walkSiteEntity.getWhetherOpenAnswer().equals(EnableOrNotEnum.On.getStatus())) {
                ActivityBriskWalkSiteAnswerConfigEntity configEntity = activityBriskWalkSiteAnswerConfigDao.selectOne(new LambdaQueryWrapper<ActivityBriskWalkSiteAnswerConfigEntity>()
                        .eq(ActivityBriskWalkSiteAnswerConfigEntity::getWalkActivitySiteId, vo.getBriskWalkSiteId())
                        .eq(ActivityBriskWalkSiteAnswerConfigEntity::getWalkActivityId, vo.getBriskWalkId()));
                //判断用户答了几次
                List<UserContestSiteAnswerRecordsEntity> recordsEntityList = userContestSiteAnswerRecordsDao.selectList(new LambdaQueryWrapper<UserContestSiteAnswerRecordsEntity>()
                        .eq(UserContestSiteAnswerRecordsEntity::getWalkActivitySiteId, vo.getBriskWalkSiteId())
                        .eq(UserContestSiteAnswerRecordsEntity::getWalkActivityId, vo.getBriskWalkId()));
                if (recordsEntityList.size() >= configEntity.getSiteAnswerNumber()) {
                    throw new ServerException("该站点错答数量已超过限制数量");
                }
            }
            //站点答题
            points = userContestQuestionService.
                    save(vo.getBriskWalkId(), vo.getBriskWalkSiteId(), null, ActivityQuestionTypeEnum.WALK_ACTIVITY.getBusinessType(), vo.getUserAnswerQuestionBankList());
            //需要判断是否全部答对
            if (points >= 0) {
                //进行集卡活动
                addCard(walkSiteEntity);
                //同时需要解锁这个站点
                UserUnlockSiteEntity unlockSiteEntity = new UserUnlockSiteEntity().setWalkActivityId(vo.getBriskWalkId()).setWalkActivitySiteId(vo.getBriskWalkSiteId()).setUserId(SecurityUser.getUserId()).setSiteSort(walkSiteEntity.getSiteSort());
                userUnlockSiteDao.insert(unlockSiteEntity);
                points += walkSiteEntity.getUnlockPoints();
                userAnswerQuestionTimeService.completedUserAnswerQuestion(vo.getBriskWalkId(), vo.getBriskWalkSiteId(), UserAnswerQuestionEnum.WALK_ACTIVITY.getType());
            }
        }
        if (points > 0) {
            //增加积分
            userPointsRecordsService.insertUserPointsRecords(vo.getBriskWalkId(), ActivityTypeEnum.WALK_ACTIVITY.getBusinessType(), points, WhetherAddEnum.ADD.getType());
        }
        return points;
    }

    /**
     * 集卡活动
     *
     * @param walkSiteEntity 站点信息
     */
    private void addCard(ActivityBriskWalkSiteEntity walkSiteEntity) {
        UserEarningsCardEntity userEarningsCardEntity = checkCard(walkSiteEntity, SecurityUser.getUserId());
        if (ObjectUtils.isEmpty(userEarningsCardEntity)) {
            return;
        }
        userEarningsCardDao.insert(userEarningsCardEntity);
    }

    /**
     * 校验站点是否需要添加卡片
     *
     * @param walkSiteEntity 站点对象数据
     * @param userId         用户id
     * @return 卡片对象
     */
    private UserEarningsCardEntity checkCard(ActivityBriskWalkSiteEntity walkSiteEntity, Long userId) {
        if (walkSiteEntity.getWhetherCard().equals(Constant.ZERO)) {
            return null;
        }
        UserEarningsCardEntity userEarningsCardEntity = new UserEarningsCardEntity();
        userEarningsCardEntity.setBriskWalkId(walkSiteEntity.getWalkActivityId());
        userEarningsCardEntity.setBriskWalkSiteId(walkSiteEntity.getId());
        userEarningsCardEntity.setCardName(walkSiteEntity.getCardName());
        userEarningsCardEntity.setUserId(userId);
        userEarningsCardEntity.setCardPicture(walkSiteEntity.getCardPicture());
        return userEarningsCardEntity;
    }

    /**
     * 校验是否答过题
     *
     * @param walkFeatureId 站点关联id
     * @param featureEntity 站点关联实体类
     */
    private void checkAnswer(Long walkFeatureId, ActivityBriskWalkFeatureEntity featureEntity) {
        LambdaQueryWrapper<UserEverydayContestQuestionEntity> queryWrapper = new LambdaQueryWrapper<UserEverydayContestQuestionEntity>();
        boolean todayFlag = true;
        if (ObjectUtils.isEmpty(featureEntity)) {
            setEveryDay(queryWrapper, walkFeatureId);
        } else {
            if (featureEntity.getWhetherRandom().equals(WhetherRandomEnum.NO.getType())) {
                queryWrapper.eq(UserEverydayContestQuestionEntity::getWalkFeatureId, featureEntity.getId());
                todayFlag = false;
            } else {
                setEveryDay(queryWrapper, featureEntity.getId());
            }
        }
        UserEverydayContestQuestionEntity checkEntity = userEverydayContestQuestionDao.selectOne(queryWrapper);
        if (ObjectUtils.isNotEmpty(checkEntity)) {
            if (todayFlag) {
                throw new ServerException("今日答题已完成");
            } else {
                throw new ServerException("答题已完成");
            }
        }
    }

    /**
     * 是否答题查询器设置过滤值
     *
     * @param queryWrapper  查询器
     * @param walkFeatureId 站点关联id
     */
    private void setEveryDay(LambdaQueryWrapper<UserEverydayContestQuestionEntity> queryWrapper, Long walkFeatureId) {
        queryWrapper.eq(UserEverydayContestQuestionEntity::getWalkFeatureId, walkFeatureId)
                .eq(UserEverydayContestQuestionEntity::getUserId, SecurityUser.getUserId())
                .le(UserEverydayContestQuestionEntity::getCreateTime, LocalDateTime.of(LocalDate.now(), LocalTime.MAX))
                .ge(UserEverydayContestQuestionEntity::getCreateTime, LocalDateTime.of(LocalDate.now(), LocalTime.MIN));
    }

    private final static String EVERY_DAY = "everyDay:";

    @Override
    public synchronized List<ActivityContestQuestionVO> everydayQuestion(Long walkFeatureId) {
        String key = EVERY_DAY + walkFeatureId + ":" + LocalDate.now().toEpochDay();
        checkAnswer(walkFeatureId, null);
        String check = (String) redisCache.get(key);
        ActivityBriskWalkFeatureEntity featureEntity = activityBriskWalkFeatureDao.selectById(walkFeatureId);
        userAnswerQuestionTimeService.insertUserAnswerQuestion(featureEntity.getBriskWalkId(), featureEntity.getBusinessId(), UserAnswerQuestionEnum.WALK_ACTIVITY.getType());
        if (StringUtils.isNotEmpty(check)) {
            //如果已存在，则直接拿最新的
            List<Long> questionIdList = JSONArray.parseArray(check, Long.class);
            return activityContestQuestionService.findByQuestionIdList(questionIdList);
        } else {
            List<ActivityContestQuestionVO> contestQuestionVOList = activityContestQuestionService.findByBusinessIdList(Collections.singletonList(featureEntity.getBusinessId()), ActivityQuestionTypeEnum.KNOWLEDGE_CONTEST.getBusinessType());
            List<UserEverydayContestQuestionEntity> alreadyEntityList = userEverydayContestQuestionDao.selectList(new LambdaQueryWrapper<UserEverydayContestQuestionEntity>()
                    .eq(UserEverydayContestQuestionEntity::getUserId, SecurityUser.getUserId())
                    .eq(UserEverydayContestQuestionEntity::getWalkActivityId, featureEntity.getBriskWalkId()));
            List<Long> contestQuestionIdList = new ArrayList<>();
            if (CollectionUtils.isNotEmpty(alreadyEntityList)) {
                alreadyEntityList.forEach(item -> {
                    contestQuestionIdList.addAll(item.getContestQuestionIds());
                });
            }
            List<ActivityContestQuestionVO> randomContestQuestionList = randomContestQuestion(contestQuestionVOList, contestQuestionIdList, featureEntity.getRandomNumber());
            redisCache.set(key, JSONArray.toJSONString(randomContestQuestionList.stream().map(ActivityContestQuestionVO::getId).toList()), RedisCache.DEFAULT_EXPIRE);
            return randomContestQuestionList;
        }
    }

    /**
     * 抽取数据
     *
     * @param source        全部的题目
     * @param excludeIds    已经答过的题目id
     * @param requiredCount 随机数量
     * @return 结果
     */
    public List<ActivityContestQuestionVO> randomContestQuestion(List<ActivityContestQuestionVO> source,
                                                                 List<Long> excludeIds,
                                                                 int requiredCount) {
        // 基础校验
        if (CollectionUtils.isEmpty(source)) {
            return Collections.emptyList();
        }
        if (requiredCount <= 0) {
            return Collections.emptyList();
        }
        // 构建快速检索结构
        Map<Long, ActivityContestQuestionVO> questionMap = source.stream()
                .collect(Collectors.toMap(ActivityContestQuestionVO::getId, Function.identity()));

        Set<Long> excludeSet = new HashSet<>(excludeIds);
        List<Long> candidates = source.stream()
                .map(ActivityContestQuestionVO::getId)
                .filter(id -> !excludeSet.contains(id))
                .collect(Collectors.toList());

        // 计算实际可抽取量
        int actualCount = Math.min(requiredCount, candidates.size());
        if (actualCount == 0) {
            return Collections.emptyList();
        }

        // 高效随机算法
        Collections.shuffle(candidates);
        return candidates.stream()
                .limit(actualCount)
                .map(questionMap::get)
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
    }

    @Override
    public PageResult<UserSnapshotVO> lookSnapshot(WalkUserSnapshotQuery query) {
        UserSnapshotQuery userSnapshotQuery = BeanUtil.copyProperties(query, UserSnapshotQuery.class);
        userSnapshotQuery.setBusinessId(query.getWalkId());
        userSnapshotQuery.setBusinessSonId(query.getWalkSiteId());
        userSnapshotQuery.setBusinessType(ActivityTypeEnum.WALK_ACTIVITY.getBusinessType());
        userSnapshotQuery.setSnapshotFlag(false);
        userSnapshotQuery.setSeeType(query.getSeeType());
        return userSnapshotService.page(userSnapshotQuery);
    }

    @Override
    public SelfCardVO getSelfCard(Long briskWalkId) {
        SelfCardVO selfCardVO = new SelfCardVO();
        List<ActivityBriskWalkSiteEntity> briskWalkSiteEntityList = activityBriskWalkSiteService.list(new LambdaQueryWrapper<ActivityBriskWalkSiteEntity>()
                .eq(ActivityBriskWalkSiteEntity::getWhetherCard, Constant.ENABLE).eq(ActivityBriskWalkSiteEntity::getWalkActivityId, briskWalkId));
        if (CollectionUtils.isNotEmpty(briskWalkSiteEntityList)) {
            selfCardVO.setActivityCardList(briskWalkSiteEntityList.stream().filter(item -> StringUtils.isNotEmpty(item.getCardName())).map(entity -> {
                return new CardVO().setId(entity.getId()).setCardName(entity.getCardName()).setCardPicture(entity.getCardPicture());
            }).toList());
            List<UserEarningsCardEntity> earningsCardEntityList = userEarningsCardDao.selectList(new LambdaQueryWrapper<UserEarningsCardEntity>().eq(UserEarningsCardEntity::getUserId, SecurityUser.getUserId())
                    .eq(UserEarningsCardEntity::getBriskWalkId, briskWalkId));
            if (CollectionUtils.isNotEmpty(earningsCardEntityList)) {
                selfCardVO.setSelfCardList(earningsCardEntityList.stream().map(entity -> {
                    return new CardVO().setId(entity.getBriskWalkSiteId()).setCardName(entity.getCardName()).setCardPicture(entity.getCardPicture());
                }).toList());
            }
        }
        return selfCardVO;
    }

    @Override
    public List<AlreadyAnswerQuestionBankVO> alreadyAnswer(Long walkFeatureId) {
        ActivityBriskWalkFeatureEntity featureEntity = activityBriskWalkFeatureDao.selectById(walkFeatureId);
        String key = EVERY_DAY + walkFeatureId + ":" + LocalDate.now().toEpochDay();
        String check = (String) redisCache.get(key);
        if (StringUtils.isEmpty(check)) {
            throw new ServerException("今日未答题");
        }
        return userContestQuestionService.getAlreadyAnswer(featureEntity.getBriskWalkId(), null, true, featureEntity.getBusinessId(), ActivityQuestionTypeEnum.KNOWLEDGE_CONTEST.getBusinessType(), JSONArray.parseArray(check, Long.class));
    }


    private LambdaQueryWrapper<ActivityBriskWalkEntity> getWrapper(ActivityBriskWalkQuery query) {
        LambdaQueryWrapper<ActivityBriskWalkEntity> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(ActivityBriskWalkEntity::getStatus, Constant.ENABLE);
        Long orgId;
        if (ObjectUtils.isNotEmpty(SecurityUser.getUser())) {
            SecurityUser.getUser().getOrgId();
            if (ObjectUtils.isNotEmpty(query.getOrgId())) {
                orgId = query.getOrgId();
            } else {
                orgId = null;
            }
        } else {
            if (ObjectUtils.isNotEmpty(query.getOrgId())) {
                orgId = query.getOrgId();
            } else {
                orgId = null;
            }
        }
        if (ObjectUtils.isNotEmpty(orgId)) {
            wrapper.and(wrapper1 -> {
                wrapper1.apply("JSON_CONTAINS(join_org_id, CAST({0} AS JSON))", orgId).or().eq(ActivityBriskWalkEntity::getOrgId, orgId);
            });
        }
        wrapper.orderByDesc(ActivityBriskWalkEntity::getUpdateTime);
        return wrapper;
    }

    @Scheduled(cron = "0 0/10 * * * ? ")
    @Transactional(rollbackFor = Exception.class)
    public void updateActivityEndStatus() {
        List<ActivityBriskWalkEntity> entityList = this.list(new LambdaQueryWrapper<ActivityBriskWalkEntity>().eq(ActivityBriskWalkEntity::getActivityStatus, ActivityStatusEnum.BEGIN.getStatus())
                .apply("date_format(activity_end_time,'%Y-%m-%d %H:%i:%s') <= date_format ({0},'%Y-%m-%d %H:%i:%s')", DateUtils.format(new Date(), DateUtils.DATE_TIME_PATTERN)));
        if (CollectionUtils.isNotEmpty(entityList)) {
            entityList.forEach(item -> {
                item.setActivityStatus(ActivityStatusEnum.END.getStatus());
            });
            this.saveOrUpdateBatch(entityList);
            //活动结束--自动点亮最后一个站点
            autoLightLastStation(entityList);
        }
        List<ActivityBriskWalkEntity> notStartList = this.list(new LambdaQueryWrapper<ActivityBriskWalkEntity>().eq(ActivityBriskWalkEntity::getActivityStatus, ActivityStatusEnum.NOT_START.getStatus())
                .apply("date_format(activity_start_time,'%Y-%m-%d %H:%i:%s') <= date_format ({0},'%Y-%m-%d %H:%i:%s')", DateUtils.format(new Date(), DateUtils.DATE_TIME_PATTERN)));
        if (CollectionUtils.isNotEmpty(notStartList)) {
            notStartList.forEach(item -> {
                item.setActivityStatus(ActivityStatusEnum.BEGIN.getStatus());
            });
            this.saveOrUpdateBatch(notStartList);
        }
    }

    @Override
    public void autoLightLastStationTest() {
        List<ActivityBriskWalkEntity> entityList = new ArrayList<>();
        entityList.add(this.getById(18L));
        autoLightLastStation(entityList);
    }

    @Override
    public Result<Object> unlockFixedSite(String mobile, String siteNumber) {
        List<MemberUserEntity>  memberUserEntities
                =  memberUserDao.selectList(new LambdaQueryWrapper<MemberUserEntity>().in(MemberUserEntity::getMobile, mobile).
                orderByDesc(MemberUserEntity::getCreateTime));
        if (memberUserEntities == null || memberUserEntities.isEmpty()){
            return Result.error("未找到该用户,请确认手机号是否正确");
        }
        int site = Integer.parseInt(siteNumber);
        if (site == 0){
            return Result.error("开启站点数量不能为0");
        }
        // Calculate days from May 1st to today
        LocalDate mayFirst = LocalDate.of(LocalDate.now().getYear(), 5, 1);
        LocalDate today = LocalDate.now();
        long daysBetween = ChronoUnit.DAYS.between(mayFirst, today) + 1;
        if (daysBetween  < site) {
            return Result.error("解锁地图数量不能大于天数");
        }

        log.info("获取到用户信息 {}",memberUserEntities);
        MemberUserEntity m = memberUserEntities.get(0);
        m.setPoints(site*10.0);
        memberUserDao.updateById(m);
        Long userId = m.getId();
        userUnlockSiteDao.forceDeleteByUserId(userId);
        for (int i = 0; i < site; i++) {
            UserUnlockSiteEntity unlockSiteEntity = new UserUnlockSiteEntity().setWalkActivityId(31L).setWalkActivitySiteId(i+244L).setUserId(userId).setSiteSort(i+1);
            unlockSiteEntity.setCreateTime(LocalDateTime.now().minusDays(1));
            unlockSiteEntity.setUpdateTime(unlockSiteEntity.getCreateTime());
            unlockSiteEntity.setUpdater(userId);
            unlockSiteEntity.setCreator(userId);
            userUnlockSiteDao.insertWithFixedTime(unlockSiteEntity);
        }
        userPointsRecordsDao.forceDeleteByUserId(userId);
        for (int i = 0; i < site; i++) {
            UserPointsRecordsEntity entity = new UserPointsRecordsEntity();
            entity.setBusinessId(31L);
            entity.setBusinessType(7);
            entity.setPoints(10.00);
            entity.setWhetherAdd(1);
            entity.setUserId(userId);
            userPointsRecordsDao.insert(entity);
        }

        return Result.ok("用户 " + m.getRealName() +" id " + m.getId() + "已解锁"+siteNumber+"站点");
    }

    /**
     * 自动点亮最后一个站点
     *
     * @param entityList 待点亮的健步走活动对象数组
     */
    private void autoLightLastStation(List<ActivityBriskWalkEntity> entityList) {
        List<ActivityBriskWalkEntity> filterEntityList = entityList.stream().filter(item -> item.getFunctionPanel().contains(Constant.ENABLE)).toList();
        if (CollectionUtils.isEmpty(filterEntityList)) {
            return;
        }
        List<Long> walkIdList = filterEntityList.stream().map(ActivityBriskWalkEntity::getId).toList();
        List<ActivityBriskWalkSiteEntity> walkSiteEntityList = activityBriskWalkSiteService.list(new LambdaQueryWrapper<ActivityBriskWalkSiteEntity>().in(ActivityBriskWalkSiteEntity::getWalkActivityId, walkIdList));
        if (CollectionUtils.isEmpty(walkSiteEntityList)) {
            return;
        }
        List<UserJoinActivityEntity> userJoinActivityEntityList = userJoinActivityService.list(new LambdaQueryWrapper<UserJoinActivityEntity>()
                .in(UserJoinActivityEntity::getActivityId, walkIdList).eq(UserJoinActivityEntity::getBusinessType, ActivityTypeEnum.WALK_ACTIVITY.getBusinessType()));
        if (CollectionUtils.isEmpty(userJoinActivityEntityList)) {
            return;
        }
        Map<Long, Set<Long>> joinActivityUserIdMap = userJoinActivityEntityList.stream()
                .filter(e -> e.getActivityId() != null && e.getUserId() != null)
                .collect(Collectors.groupingBy(
                        UserJoinActivityEntity::getActivityId,
                        LinkedHashMap::new,
                        Collectors.mapping(
                                UserJoinActivityEntity::getUserId,
                                Collectors.toSet()
                        )
                ));
        List<UserUnlockSiteEntity> unlockSiteEntityList = new ArrayList<>();
        List<UserEarningsCardEntity> earningsCardEntityList = new ArrayList<>();
        Map<Long, ActivityBriskWalkSiteEntity> walkSiteMap = walkSiteEntityList.stream()
                .filter(Objects::nonNull)
                .filter(e -> e.getWalkActivityId() != null)
                .collect(Collectors.toMap(
                        ActivityBriskWalkSiteEntity::getWalkActivityId,
                        Function.identity(),
                        (oldVal, newVal) -> oldVal.getSiteSort() > newVal.getSiteSort() ? oldVal : newVal,
                        LinkedHashMap::new
                ));
        //获取到最后一个站点已经点亮的人数
        ActivityBriskWalkSiteEntity walkSiteEntity = walkSiteMap.get(18L);
        List<UserUnlockSiteEntity> unlockSiteEntities = userUnlockSiteDao.selectList(new LambdaQueryWrapper<UserUnlockSiteEntity>().eq(UserUnlockSiteEntity::getWalkActivityId, walkSiteEntity.getWalkActivityId())
                .eq(UserUnlockSiteEntity::getWalkActivitySiteId, walkSiteEntity.getId()));
        List<Long> alreadyUserIdList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(unlockSiteEntities)) {
            alreadyUserIdList.addAll(unlockSiteEntities.stream().map(UserUnlockSiteEntity::getUserId).toList());
        }
        walkSiteMap.forEach((key, activityBriskWalkSiteEntity) -> {
            Set<Long> userIdList = joinActivityUserIdMap.get(key);
            Set<Long> excludeSet = new HashSet<>(alreadyUserIdList);
            userIdList.removeIf(excludeSet::contains);
            if (CollectionUtils.isNotEmpty(userIdList)) {
                if (activityBriskWalkSiteEntity.getWhetherCard().equals(Constant.ENABLE)) {
                    userIdList.forEach(userId -> {
                        unlockSiteEntityList.add(new UserUnlockSiteEntity().setUserId(userId)
                                .setWalkActivitySiteId(activityBriskWalkSiteEntity.getId())
                                .setWalkActivityId(activityBriskWalkSiteEntity.getWalkActivityId())
                                .setSiteSort(activityBriskWalkSiteEntity.getSiteSort()));
                        earningsCardEntityList.add(checkCard(activityBriskWalkSiteEntity, userId));
                    });
                } else {
                    userIdList.forEach(userId -> {
                        unlockSiteEntityList.add(new UserUnlockSiteEntity().setUserId(userId)
                                .setWalkActivitySiteId(activityBriskWalkSiteEntity.getId())
                                .setWalkActivityId(activityBriskWalkSiteEntity.getWalkActivityId())
                                .setSiteSort(activityBriskWalkSiteEntity.getSiteSort()));
                    });
                }
            }
        });
        //解锁站点数据入库
        if (CollectionUtils.isNotEmpty(unlockSiteEntityList)) {
//            userUnlockSiteDao.insertOrUpdate(unlockSiteEntityList);
            userUnlockSiteDao.insertBatchData(unlockSiteEntityList);
        }
        //待插入卡片数据入库
        if (CollectionUtils.isNotEmpty(earningsCardEntityList)) {
//            userEarningsCardDao.insertOrUpdate(earningsCardEntityList);
            userEarningsCardDao.insertBatchData(earningsCardEntityList);
        }
    }


//    /**
//     * 自动点亮最后一个站点
//     *
//     * @param entityList 待点亮的健步走活动对象数组
//     */
//    private void autoLightLastStation(List<ActivityBriskWalkEntity> entityList) {
//        List<ActivityBriskWalkEntity> filterEntityList = entityList.stream().filter(item -> item.getFunctionPanel().contains(Constant.ENABLE)).toList();
//        if (CollectionUtils.isEmpty(filterEntityList)) {
//            return;
//        }
//        List<Long> walkIdList = filterEntityList.stream().map(ActivityBriskWalkEntity::getId).toList();
//        List<UserUnlockSiteEntity> userUnlockSiteEntityList = userUnlockSiteDao.selectList(new LambdaQueryWrapper<UserUnlockSiteEntity>().in(UserUnlockSiteEntity::getWalkActivityId, walkIdList));
//        Map<Long, Map<Long, List<UserUnlockSiteEntity>>> userUnlockMap = userUnlockSiteEntityList.stream().collect(Collectors.groupingBy(UserUnlockSiteEntity::getUserId, Collectors.groupingBy(UserUnlockSiteEntity::getWalkActivityId,
//                Collectors.collectingAndThen(
//                        Collectors.toList(),
//                        list -> list.stream()
//                                .sorted(Comparator.comparingLong(UserUnlockSiteEntity::getSiteSort))
//                                .collect(Collectors.toList())
//                ))));
//        List<ActivityBriskWalkSiteEntity> walkSiteEntityList = activityBriskWalkSiteService.list(new LambdaQueryWrapper<ActivityBriskWalkSiteEntity>().in(ActivityBriskWalkSiteEntity::getWalkActivityId, walkIdList));
//        if (CollectionUtils.isEmpty(walkSiteEntityList)) {
//            return;
//        }
//        List<UserUnlockSiteEntity> unlockSiteEntityList = new ArrayList<>();
//        List<UserEarningsCardEntity> earningsCardEntityList = new ArrayList<>();
//        Map<Long, List<ActivityBriskWalkSiteEntity>> walkSiteMap = walkSiteEntityList.stream().collect(Collectors.groupingBy(ActivityBriskWalkSiteEntity::getWalkActivityId,
//                Collectors.collectingAndThen(
//                        Collectors.toList(),
//                        list -> list.stream()
//                                .sorted(Comparator.comparingLong(ActivityBriskWalkSiteEntity::getSiteSort))
//                                .collect(Collectors.toList())
//                )));
//        List<List<Long>> splitList = ListUtil.splistList(new ArrayList<>(userUnlockMap.keySet()), Constant.THREAD_EXECUTE_LIST_SIZE);
//        CountDownLatch latch = new CountDownLatch(splitList.size());
//        splitList.forEach(listItem -> ThreadPoolExecutorUtil.getThreadPool().execute(() -> {
//            autoLightUserStation(listItem, userUnlockMap, walkSiteMap, unlockSiteEntityList, earningsCardEntityList);
//            latch.countDown();
//        }));
//        try {
//            latch.await();
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }
//        //解锁站点数据入库
//        if (CollectionUtils.isNotEmpty(unlockSiteEntityList)) {
//            userUnlockSiteDao.insertOrUpdate(unlockSiteEntityList);
//        }
//        //待插入卡片数据入库
//        if (CollectionUtils.isNotEmpty(earningsCardEntityList)) {
//            userEarningsCardDao.insertOrUpdate(earningsCardEntityList);
//        }
//    }

    /**
     * 校验用户最后的一个站点
     *
     * @param userIdList             用户id数组
     * @param userUnlockMap          用户已经点亮的站点
     * @param walkSiteMap            站点数据map
     * @param unlockSiteEntityList   待插入解锁的站点数组
     * @param earningsCardEntityList 待插入的卡片数据
     */
    private void autoLightUserStation(List<Long> userIdList, Map<Long, Map<Long, List<UserUnlockSiteEntity>>> userUnlockMap, Map<Long, List<ActivityBriskWalkSiteEntity>> walkSiteMap, List<UserUnlockSiteEntity> unlockSiteEntityList, List<UserEarningsCardEntity> earningsCardEntityList) {
        //用户id循环
        userIdList.forEach(item -> {
            Map<Long, List<UserUnlockSiteEntity>> userUnlockSiteMap = userUnlockMap.get(item);
            if (ObjectUtils.isNotEmpty(userUnlockSiteMap)) {
                userUnlockSiteMap.forEach((key, value) -> {
                    if (CollectionUtils.isNotEmpty(value)) {
                        UserUnlockSiteEntity unlockSiteEntity = value.get(value.size() - 1);
                        List<ActivityBriskWalkSiteEntity> walkSiteEntityList = walkSiteMap.get(key);
                        int index = -1;
                        for (int i = 0; i < walkSiteEntityList.size(); i++) {
                            ActivityBriskWalkSiteEntity walkSiteEntity = walkSiteEntityList.get(i);
                            if (unlockSiteEntity.getSiteSort() < walkSiteEntity.getSiteSort()) {
                                index = i;
                                break;
                            }
                        }
                        if (index >= Constant.ZERO) {
                            ActivityBriskWalkSiteEntity checkEntity = walkSiteEntityList.get(index);
                            //添加解锁站点
                            unlockSiteEntityList.add(new UserUnlockSiteEntity().setUserId(item)
                                    .setWalkActivitySiteId(checkEntity.getId())
                                    .setWalkActivityId(checkEntity.getWalkActivityId())
                                    .setSiteSort(checkEntity.getSiteSort()));
                            //校验卡片
                            earningsCardEntityList.add(checkCard(checkEntity, item));
                        }
                    }
                });
            }
        });
    }


    @Scheduled(cron = "0 0/10 * * * ? ")
    @Transactional(rollbackFor = Exception.class)
    public void generateRankSnapshot() {
        //读取redis里面步数的数据
        List<ActivityBriskWalkEntity> entityList = this.list(new LambdaQueryWrapper<ActivityBriskWalkEntity>().eq(ActivityBriskWalkEntity::getActivityStatus, ActivityStatusEnum.BEGIN.getStatus())
                .apply("date_format(activity_end_time,'%Y-%m-%d %H:%i:%s') >= date_format ({0},'%Y-%m-%d %H:%i:%s')", DateUtils.format(new Date(), DateUtils.DATE_TIME_PATTERN)));
        if (CollectionUtils.isNotEmpty(entityList)) {
            entityList.forEach(item -> {
                String key = "step_key:" + item.getId() + ":";
                List<UserJourneyEntity> userJourneyEntityList = new ArrayList<>();
                Pattern NUMERIC_PATTERN = Pattern.compile("^[-+]?\\d+(\\.\\d+)?([eE][-+]?\\d+)?$");
                Map<Object, Object> result = redisCache.getValuesByPrefix(key);
                Map<String, Set<Long>> stepDateMap = new HashMap();
                result.forEach((itemKey, value) -> {
                    if (NUMERIC_PATTERN.matcher(value.toString()).matches()) {
                        String userId = String.valueOf(itemKey).split(":")[2];
                        String stepDate = String.valueOf(itemKey).split(":")[3];
                        int count = Integer.parseInt(value.toString());
                        Set<Long> userIdList = stepDateMap.get(stepDate);
                        if (CollectionUtils.isEmpty(userIdList)) {
                            userIdList = new HashSet<>();
                        }
                        userIdList.add(Long.parseLong(userId));
                        stepDateMap.put(stepDate, userIdList);
                        UserJourneyEntity entity = new UserJourneyEntity();
                        entity.setUserId(Long.parseLong(userId));
                        entity.setStepDate(LocalDate.ofEpochDay(Long.parseLong(stepDate)));
                        entity.setWalkActivityId(item.getId());
                        entity.setStepNumber(count > 20000 ? 20000 : count);
                        userJourneyEntityList.add(entity);
                    }
                });
                //进行更新删除操作
                stepDateMap.forEach((itemKey, value) -> {
                    userJourneyDao.delete(new LambdaQueryWrapper<UserJourneyEntity>().eq(UserJourneyEntity::getWalkActivityId, item.getId())
                            .eq(UserJourneyEntity::getStepDate, LocalDate.ofEpochDay(Long.parseLong(itemKey)))
                            .in(UserJourneyEntity::getUserId, value));
                    userJourneyDao.insertBatchData(userJourneyEntityList);
                });
            });
        }
    }


}